
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>面试被问 Java为什么有这么多O - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>面试被问 Java为什么有这么多O - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">为什么在Java企业级应用中需要使用PO, DTO, VO等多种不同的对象模型，而不是只用一个类来处理所有事情？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">这是为了解决软件工程中的核心问题：“关注点分离”。随着应用规模的扩大，每一层（如表现层、业务层、持久层）都有其特定的职责和关注点，因此需要专门的对象模型来承载数据，避免将所有功能都挤在一个对象里导致混乱和相互影响。</div>
          </div>
          <div class="card-source">来源: 1、Java对象模型的起源与演变</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">请解释 PO (Persistent Object), DTO (Data Transfer Object), 和 VO (View Object) 的核心区别与各自的使用场景。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">PO (持久化对象) 与数据库表结构对应，用于持久化层；DTO (数据传输对象) 用于层间数据传输，只包含必要的数据，不含业务逻辑；VO (视图对象) 面向前端展示，关注数据如何被呈现，可能包含格式化后的数据。</div>
          </div>
          <div class="card-source">来源: 4、面试官最爱问的对象模型问题</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">BO (Business Object) 在Java对象模型中扮演什么角色？它与其他对象模型（如PO）有何不同？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">BO (业务对象) 封装了业务逻辑和规则，是业务处理的核心，就像是"业务专家"。它与其他对象模型的不同之处在于，它不仅包含数据（如PO），还包含了复杂的业务逻辑方法，用于根据数据做出业务决策。</div>
          </div>
          <div class="card-source">来源: 2、常见的Java对象模型</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">实践</div>
          <div class="card-question">为什么在API接口中直接返回数据库实体（Entity/PO）被认为是一种不好的做法？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">实践</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">直接返回实体会导致四个主要问题：1. **耦合问题**：数据库结构变更会直接影响接口；2. **安全问题**：可能暴露密码哈希等敏感字段；3. **性能问题**：可能传输不必要的大量数据；4. **版本控制困难**：难以实现接口的向后兼容。</div>
          </div>
          <div class="card-source">来源: 4、面试官最爱问的对象模型问题</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">MapStruct 和 ModelMapper 在处理对象映射时最根本的区别是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">最根本的区别在于处理方式：MapStruct 是一个代码生成器，在“编译时”生成映射代码，性能高且类型安全；而 ModelMapper 是一个运行时库，它使用“运行时反射”来动态映射对象，虽然开发速度快但有性能开销且非类型安全。</div>
          </div>
          <div class="card-source">来源: 6、MapStruct 与 ModelMapper</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">根据文档，如果你在大型企业级应用中更关注性能和类型安全，应该选择哪种对象映射工具？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">如果你关注性能和类型安全，应该选择 MapStruct。因为它在编译时生成映射代码，没有运行时性能开销，并且可以在编译阶段检查类型匹配问题。</div>
          </div>
          <div class="card-source">来源: 6、MapStruct 与 ModelMapper</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">实践</div>
          <div class="card-question">在进行对象模型之间的转换时，有哪些常见的陷阱或问题需要注意？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">实践</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">常见的陷阱包括：1. 性能问题（过度转换导致性能下降）；2. 循环引用（对象间相互引用导致无限递归）；3. 数据丢失（转换过程中丢失重要信息）；4. 延迟加载失效（在ORM框架中转换后可能无法访问延迟加载的属性）。</div>
          </div>
          <div class="card-source">来源: 3、对象模型的实战应用</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">当项目规模扩大时，如何避免因对象模型数量迅速增多而导致的"对象爆炸"问题？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">文档提出了三种控制方法：1. 合理复用，在相似场景中共用对象模型；2. 组合而非继承，使用组合模式来减少类的数量；3. 动态构建，例如使用构建者模式（Builder Pattern）根据需要动态构建对象，而不是为每种情况都创建新类。</div>
          </div>
          <div class="card-source">来源: 5、对象模型的实战</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">实践</div>
          <div class="card-question">在微服务架构下，对象模型的设计有哪些关键点需要特别关注？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">实践</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在微服务架构中，对象模型设计需要关注：1. 服务边界明确，每个服务有自己的对象模型；2. 契约优先，API契约决定DTO的设计；3. 版本管理，对象模型需要考虑向后兼容性；4. 序列化效率，考虑网络传输效率，例如使用 Protocol Buffers。</div>
          </div>
          <div class="card-source">来源: 5、对象模型的实战</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
